package ar.edu.utn.frba.tacs.warnes;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;

import org.junit.After;
import org.junit.Before;
import org.junit.Test;

import ar.edu.utn.frba.tacs.warnes.entities.Pieza;
import ar.edu.utn.frba.tacs.warnes.entities.Venta;
import ar.edu.utn.frba.tacs.warnes.excepciones.NoPuedoVenderPiezaDisponibleException;
import ar.edu.utn.frba.tacs.warnes.excepciones.YaEstaVendidaException;
import ar.edu.utn.frba.tacs.warnes.pieza.PiezaReservadaState;
import ar.edu.utn.frba.tacs.warnes.pieza.PiezaVendidaState;
import ar.edu.utn.frba.tacs.warnes.utils.ConstantesWarnes;
import ar.edu.utn.frba.tacs.warnes.utils.ContenedorWarnes;

public class VentaTestCase {
	private ContenedorWarnes contenedor;
	private Pieza pieza;

	@Before
	public void inicializaciones() {
		this.contenedor = ContenedorWarnes.getInstance();
		
		this.pieza = this.contenedor.creaUnaPieza("Espejito");
		this.pieza.setId(new Long(1));
		this.pieza.setCategoria(ConstantesWarnes.Categoria.PARTES);
		this.pieza.setDescripcion("Rueda");
	}

	@After
	public void limpiarContenedor() {
		this.contenedor.limpiate();
	}
	
	/**
	 * Testea que la pieza se reserve correctamente
	 */
	@Test
	public void testVenderPiezas() {
		Venta venta = this.contenedor.nuevaVenta();	
		Pieza pieza2 = this.contenedor.creaUnaPieza("Distribuidor");
		Pieza pieza3 = this.contenedor.creaUnaPieza("Amortiguador");

		this.pieza.cambiarEstado(PiezaReservadaState.getInstance());
		pieza2.cambiarEstado(PiezaReservadaState.getInstance());
		venta.venderPieza(this.pieza);
		venta.venderPieza(pieza2);
		
		assertTrue(venta.tienePieza(this.pieza));
		assertTrue(venta.tienePieza(pieza2));
		assertFalse(venta.tienePieza(pieza3));
		
		assertTrue(this.pieza.estaVendida());
		assertTrue(pieza2.estaVendida());
		assertFalse(pieza3.estaVendida());
		
		assertEquals(1, this.contenedor.getPiezas(ConstantesWarnes.PiezaState.DISPONIBLE).size());
		assertEquals(0, this.contenedor.getPiezas(ConstantesWarnes.PiezaState.RESERVADA).size());
		assertEquals(2, this.contenedor.getPiezas(ConstantesWarnes.PiezaState.VENDIDA).size());
	}
	
	/**
	 * Testea que no se pueda vender una pieza disponible
	 */
	@Test(expected = NoPuedoVenderPiezaDisponibleException.class)
	public void testVenderUnaPiezaReservada() {
		Venta venta = this.contenedor.nuevaVenta();	
		venta.venderPieza(this.pieza);
	}

	/**
	 * Testea que no se pueda vender una pieza ya vendida
	 */
	@Test(expected = YaEstaVendidaException.class)
	public void testVenderUnaPiezaVendida() {
		Venta venta = this.contenedor.nuevaVenta();		
		this.pieza.cambiarEstado(PiezaVendidaState.getInstance());
		venta.venderPieza(this.pieza);
	}
}
